package core

import (
	"context"
	"fmt"
	"time"

	"github.com/louloulin/dataflare/pkg/messages"
)

// WorkflowDefinition 是工作流定义
type WorkflowDefinition struct {
	// ID 是工作流ID
	ID string
	// Name 是工作流名称
	Name string
	// Description 是工作流描述
	Description string
	// Version 是工作流版本
	Version string
	// Sources 是工作流源
	Sources map[string]SourceDefinition
	// Processors 是工作流处理器
	Processors map[string]ProcessorDefinition
	// Sinks 是工作流接收器
	Sinks map[string]SinkDefinition
	// Edges 是工作流边
	Edges []EdgeDefinition
	// Config 是工作流配置
	Config map[string]interface{}
	// CreatedAt 是工作流创建时间
	CreatedAt time.Time
	// UpdatedAt 是工作流更新时间
	UpdatedAt time.Time
}

// SourceDefinition 是源定义
type SourceDefinition struct {
	// Type 是源类型
	Type string
	// Config 是源配置
	Config map[string]interface{}
}

// ProcessorDefinition 是处理器定义
type ProcessorDefinition struct {
	// Type 是处理器类型
	Type string
	// Config 是处理器配置
	Config map[string]interface{}
}

// SinkDefinition 是接收器定义
type SinkDefinition struct {
	// Type 是接收器类型
	Type string
	// Config 是接收器配置
	Config map[string]interface{}
}

// EdgeDefinition 是边定义
type EdgeDefinition struct {
	// From 是源节点ID
	From string
	// To 是目标节点ID
	To string
}

// WorkflowEngine 是工作流引擎
type WorkflowEngine interface {
	// DeployWorkflow 部署工作流
	DeployWorkflow(ctx context.Context, definition *WorkflowDefinition) (string, error)
	// StartWorkflow 启动工作流
	StartWorkflow(ctx context.Context, workflowID string, parameters map[string]interface{}) (string, error)
	// StopWorkflow 停止工作流
	StopWorkflow(ctx context.Context, runID string) error
	// GetWorkflowStatus 获取工作流状态
	GetWorkflowStatus(ctx context.Context, runID string) (*WorkflowStatus, error)
	// ListWorkflows 列出工作流
	ListWorkflows(ctx context.Context) ([]*messages.WorkflowInfo, error)
	// ListWorkflowInstances 列出工作流实例
	ListWorkflowInstances(ctx context.Context, workflowID string) ([]*messages.WorkflowInstanceInfo, error)
}

// WorkflowStatus 是工作流状态
type WorkflowStatus struct {
	// RunID 是工作流运行ID
	RunID string
	// WorkflowID 是工作流ID
	WorkflowID string
	// Status 是工作流状态
	Status string
	// Progress 是工作流进度(0-100)
	Progress int
	// StartTime 是工作流开始时间
	StartTime time.Time
	// EndTime 是工作流结束时间
	EndTime time.Time
	// NodeStatuses 是节点状态
	NodeStatuses map[string]string
	// Error 是工作流错误
	Error string
}

// WorkflowEngineImpl 是WorkflowEngine的实现
type WorkflowEngineImpl struct {
	// system 是系统
	system System
}

// NewWorkflowEngine 创建一个新的工作流引擎
func NewWorkflowEngine(system System) WorkflowEngine {
	return &WorkflowEngineImpl{
		system: system,
	}
}

// DeployWorkflow 部署工作流
func (e *WorkflowEngineImpl) DeployWorkflow(ctx context.Context, definition *WorkflowDefinition) (string, error) {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送部署工作流命令
	response, err := workflowSupervisor.Request(&messages.DeployWorkflowCommand{
		WorkflowID: definition.ID,
		Definition: definition,
	}, 30000)
	if err != nil {
		return "", err
	}

	// 解析响应
	deployResponse, ok := response.(*messages.DeployWorkflowResponse)
	if !ok {
		return "", fmt.Errorf("unexpected response type: %T", response)
	}

	if !deployResponse.Success {
		return "", fmt.Errorf("failed to deploy workflow: %s", deployResponse.Error)
	}

	return definition.ID, nil
}

// StartWorkflow 启动工作流
func (e *WorkflowEngineImpl) StartWorkflow(ctx context.Context, workflowID string, parameters map[string]interface{}) (string, error) {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送启动工作流命令
	response, err := workflowSupervisor.Request(&messages.StartWorkflowCommand{
		WorkflowID: workflowID,
		Parameters: parameters,
	}, 30000)
	if err != nil {
		return "", err
	}

	// 解析响应
	startResponse, ok := response.(*messages.StartWorkflowResponse)
	if !ok {
		return "", fmt.Errorf("unexpected response type: %T", response)
	}

	if !startResponse.Success {
		return "", fmt.Errorf("failed to start workflow: %s", startResponse.Error)
	}

	return startResponse.RunID, nil
}

// StopWorkflow 停止工作流
func (e *WorkflowEngineImpl) StopWorkflow(ctx context.Context, runID string) error {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送停止工作流命令
	response, err := workflowSupervisor.Request(&messages.StopWorkflowCommand{
		RunID: runID,
	}, 30000)
	if err != nil {
		return err
	}

	// 解析响应
	stopResponse, ok := response.(*messages.StopWorkflowResponse)
	if !ok {
		return fmt.Errorf("unexpected response type: %T", response)
	}

	if !stopResponse.Success {
		return fmt.Errorf("failed to stop workflow: %s", stopResponse.Error)
	}

	return nil
}

// GetWorkflowStatus 获取工作流状态
func (e *WorkflowEngineImpl) GetWorkflowStatus(ctx context.Context, runID string) (*WorkflowStatus, error) {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送获取工作流状态命令
	response, err := workflowSupervisor.Request(&messages.GetWorkflowStatusCommand{
		RunID: runID,
	}, 30000)
	if err != nil {
		return nil, err
	}

	// 解析响应
	statusResponse, ok := response.(*messages.GetWorkflowStatusResponse)
	if !ok {
		return nil, fmt.Errorf("unexpected response type: %T", response)
	}

	if !statusResponse.Success {
		return nil, fmt.Errorf("failed to get workflow status: %s", statusResponse.Error)
	}

	// 创建工作流状态
	status := &WorkflowStatus{
		RunID:        runID,
		Status:       statusResponse.Status,
		Progress:     statusResponse.Progress,
		StartTime:    statusResponse.StartTime,
		EndTime:      statusResponse.EndTime,
		NodeStatuses: statusResponse.NodeStatuses,
	}

	return status, nil
}

// ListWorkflows 列出工作流
func (e *WorkflowEngineImpl) ListWorkflows(ctx context.Context) ([]*messages.WorkflowInfo, error) {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送列出工作流命令
	response, err := workflowSupervisor.Request(&messages.ListWorkflowsCommand{}, 30000)
	if err != nil {
		return nil, err
	}

	// 解析响应
	listResponse, ok := response.(*messages.ListWorkflowsResponse)
	if !ok {
		return nil, fmt.Errorf("unexpected response type: %T", response)
	}

	return listResponse.Workflows, nil
}

// ListWorkflowInstances 列出工作流实例
func (e *WorkflowEngineImpl) ListWorkflowInstances(ctx context.Context, workflowID string) ([]*messages.WorkflowInstanceInfo, error) {
	// 获取工作流监督者
	workflowSupervisor := e.system.GetWorkflowSupervisor()

	// 发送列出工作流实例命令
	response, err := workflowSupervisor.Request(&messages.ListWorkflowInstancesCommand{
		WorkflowID: workflowID,
	}, 30000)
	if err != nil {
		return nil, err
	}

	// 解析响应
	listResponse, ok := response.(*messages.ListWorkflowInstancesResponse)
	if !ok {
		return nil, fmt.Errorf("unexpected response type: %T", response)
	}

	return listResponse.Instances, nil
}
